package com.uinnova.product.eam.service.impl;

import com.binary.core.util.BinaryUtils;
import com.uinnova.product.eam.comm.model.es.TemplateBinding;
import com.uinnova.product.eam.service.PlanTemplateBindService;
import com.uinnova.product.eam.service.es.PlanTemplateBindDao;
import com.uinnova.product.vmdb.comm.model.ci.CcCiClass;
import com.uino.api.client.cmdb.ICIClassApiSvc;
import com.uino.bean.cmdb.base.ESCIClassInfo;
import com.uino.bean.cmdb.business.CIClassInfoDto;
import com.uino.dao.util.ESUtil;
import com.uino.util.sys.BeanUtil;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class PlanTemplateBindServiceImpl implements PlanTemplateBindService {

   @Autowired
   private PlanTemplateBindDao planTemplateBindDao;

    @Autowired
    private ICIClassApiSvc classSvc;

    @Override
    public Integer addBind(Long classId) {
        TemplateBinding templateBinding = new TemplateBinding();
        CIClassInfoDto ciClassInfoDto = getClassInfoById(classId);
        CcCiClass ciClass = ciClassInfoDto.getCiClass();
        String className = ciClass.getClassName();
        templateBinding.setClassName(className);
        templateBinding.setClassId(classId);
        templateBinding.setId(ESUtil.getUUID());
        templateBinding.setCreateTime(BinaryUtils.getNumberDateTime());
        templateBinding.setModifyTime(BinaryUtils.getNumberDateTime());
        long count = planTemplateBindDao.countByCondition(QueryBuilders.boolQuery());
        templateBinding.setSortNum(++count);
        Long result = planTemplateBindDao.saveOrUpdate(templateBinding);
        return result.intValue();
    }

    @Override
    public List<TemplateBinding> getBindList() {
        List<SortBuilder<?>> sorts = new ArrayList<>();
        FieldSortBuilder sortNum = SortBuilders.fieldSort("sortNum").order(SortOrder.ASC);
        sorts.add(sortNum);
        List<TemplateBinding> result = planTemplateBindDao.getSortListByCdt(new TemplateBinding(), sorts);
        return result;
    }

    @Override
    public Integer deleteBindById(Long id) {
        Long sort = 0l;
        Integer result = planTemplateBindDao.deleteById(id);
        List<SortBuilder<?>> sorts = new ArrayList<>();
        FieldSortBuilder sortNum = SortBuilders.fieldSort("sortNum").order(SortOrder.ASC);
        sorts.add(sortNum);
        List<TemplateBinding> templateBindings = planTemplateBindDao.getSortListByCdt(new TemplateBinding(), sorts);
        for (TemplateBinding templateBinding : templateBindings) {
            templateBinding.setSortNum(++sort);
        }
        planTemplateBindDao.saveOrUpdateBatch(templateBindings);
        return result;
    }

    @Override
    public synchronized void dragSort(Long bindId, Long sortNum) {

        List<TemplateBinding> templateBindingList = planTemplateBindDao.getListByCdt(new TemplateBinding());

        List<TemplateBinding> sortTemplateBinding = templateBindingList.stream().filter(item -> !item.getId().equals(bindId)).sorted(Comparator.comparing(TemplateBinding::getSortNum)).collect(Collectors.toList());
        for (int i = 0; i < sortTemplateBinding.size(); i++) {
            sortTemplateBinding.get(i).setSortNum(i+1l);
        }

        for (int i = 0; i < sortTemplateBinding.size(); i++) {
            if (sortNum == i+1) {
                for (int j = (int) (sortNum - 1); j < sortTemplateBinding.size(); j++) {
                    sortTemplateBinding.get(j).setSortNum(sortTemplateBinding.get(j).getSortNum()+1);
                }
                break;
            }
        }
        TemplateBinding templateBinding = planTemplateBindDao.getById(bindId);

        templateBinding.setSortNum(sortNum);
        sortTemplateBinding.add(templateBinding);
        planTemplateBindDao.saveOrUpdateBatch(sortTemplateBinding);
    }

    @Override
    public Integer saveOrUpdateBatch(List<TemplateBinding> templateBindingList) {
        if (templateBindingList == null || templateBindingList.size() < 1) {
            return 0;
        }
        long count = planTemplateBindDao.countByCondition(QueryBuilders.boolQuery());
        for (TemplateBinding templateBinding : templateBindingList) {
            if (null == templateBinding.getId()) {
                CIClassInfoDto ciClassInfoDto = getClassInfoById(templateBinding.getClassId());
                CcCiClass ciClass = ciClassInfoDto.getCiClass();
                String className = ciClass.getClassName();
                templateBinding.setClassName(className);
                templateBinding.setId(ESUtil.getUUID());
                templateBinding.setCreateTime(BinaryUtils.getNumberDateTime());
                templateBinding.setModifyTime(BinaryUtils.getNumberDateTime());
                templateBinding.setSortNum(++count);
            }else{
                templateBinding.setModifyTime(BinaryUtils.getNumberDateTime());
            }
        }
        return  planTemplateBindDao.saveOrUpdateBatch(templateBindingList);
    }

    private CIClassInfoDto getClassInfoById(Long classId) {
        ESCIClassInfo esciClassInfo = classSvc.queryESClassInfoById(classId);
        CIClassInfoDto result = BeanUtil.converBean(esciClassInfo, CIClassInfoDto.class);
        CcCiClass ciClass = BeanUtil.converBean(esciClassInfo, CcCiClass.class);
        result.setCiClass(ciClass);
        return result;
    }
}
